(define annotate-tail-calls
  (lambda (e)
    (letrec 
        ((helper
          (lambda (e tp)
            (cond
              ((null? e) e)
              ((or (starts-with e 'const) (starts-with e 'var)) e)
              ((starts-with e 'if-3)
               (let ((test (cadr e))
                     (dit  (caddr e))
                     (dif  (cadddr e)))
                 `(if-3 ,(helper test #f)
                        ,(helper dit  tp)
                        ,(helper dif  tp))))
              ((or (starts-with e 'lambda-simple) (starts-with e 'lambda-variadic))
               (let ((args (cadr e))
                     (body (caddr e)))
                 `(,(car e) ,args ,(helper body #t))))
              ((starts-with e 'lambda-opt)
               (let ((args (cadr e))
                     (opt  (caddr e))
                     (body (cadddr e)))
                 `(,(car e) ,args ,opt ,(helper body #t))))
              ((starts-with e 'set)
               `(set ,(cadr e) ,(helper (caddr e) #f)))
              ((starts-with e 'define)
               `(define ,(cadr e) ,(helper (caddr e) #f)))
              ((starts-with e 'applic)
               (let ((operator (cadr e))
                     (operands (caddr e)))
                 (if (eq? tp #f)
                     `(applic ,(helper operator #f)
                              ,(map (lambda (operand) (helper operand #f))
                                    operands))
                     `(tc-applic ,(helper operator #f)
                                 ,(map (lambda (operand) (helper operand #f))
                                       operands)))))
              ((starts-with e 'seq)
               `(seq ,(helper (cadr e) #f)))
              ((starts-with e 'or)
               `(or ,(helper (cadr e) #f)))
              ((pair? e)
               (if (null? (cdr e))
                   `(,(helper (car e) #t))
                   `(,(helper (car e) #f) ,@(helper (cdr e) #f))))
              (else
               (error "unknown expression" e))))))
      (helper e #t))))